package top.infopub.mgr.mkt.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.infopub.dto.mkt.InquiryProDto;
import top.infopub.enums.hr.PostGroupEnum;
import top.infopub.enums.mkt.*;
import top.infopub.generic.GenericDao;
import top.infopub.generic.GenericServiceImpl;
import top.infopub.mgr.common.vo.RspVo;
import top.infopub.mgr.exception.FlowProcessException;
import top.infopub.mgr.flow.cnst.FlowTemplateEnum;
import top.infopub.mgr.flow.service.OAFlowService;
import top.infopub.mgr.flow.service.WsFlowProcessService;
import top.infopub.mgr.hr.dao.StaffInfoDao;
import top.infopub.mgr.mkt.dao.*;
import top.infopub.mgr.mkt.domain.BidCurrencyDomain;
import top.infopub.mgr.mkt.domain.InquiryProDomain;
import top.infopub.mgr.mkt.jsonvo.InquiryProJsonVo;
import top.infopub.mgr.mkt.service.InquiryProService;
import top.infopub.mgr.mkt.service.ProProcessManageService;
import top.infopub.mgr.mkt.service.SetupProService;
import top.infopub.mgr.mkt.vo.InquiryProVo;
import top.infopub.mgr.om.dao.PaymentApplyDao;
import top.infopub.mgr.om.dao.PaymentApplyDetailDao;
import top.infopub.model.hr.StaffInfo;
import top.infopub.model.mkt.*;
import top.infopub.model.om.PaymentApply;
import top.infopub.model.om.PaymentApplyDetail;
import top.infopub.security.vo.AuthorizationVO;
import top.infopub.util.IdFactory;
import top.infopub.util.UtilTools;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class InquiryProServiceImpl extends GenericServiceImpl<InquiryPro, String> implements
		InquiryProService {

	@Autowired
	private InquiryProDao inquiryProDao;

	@Autowired
    private InquiryProCoopDao inquiryProCoopDao;

    @Autowired
    private InquiryProSubDao inquiryProSubDao;

    @Autowired
    private InquiryProAttDao inquiryProAttDao;

    @Autowired
    private WsFlowProcessService wsFlowProcess;

    @Autowired
    private ProjectAttachmentDao projectAttachmentDao;

    @Autowired
    private SetupProService setupProService;

    @Autowired
    private ProjectInfoDao projectInfoDao;

    @Autowired
    private BidInfoDao bidInfoDao;

    @Autowired
    private PaymentApplyDao paymentApplyDao;

    @Autowired
    private StaffInfoDao staffInfoDao;

    @Autowired
    private PaymentApplyDetailDao paymentApplyDetailDao;

    @Autowired
    private ProProcessManageService proProcessManageService;

    @Autowired
    private BidAnalysisDao bidAnalysisDao;

    @Autowired
    private OAFlowService oaFlowService;

    @Autowired
    private BidBondApplyDao bidBondApplyDao;

	@Override
	public GenericDao<InquiryPro, String> getDao() {
		return inquiryProDao;
	}

    @Override
    public Page<BidCurrencyDomain> selectPageByDomainWhere(Page<BidCurrencyDomain> page,
                                                           InquiryProVo inquiryProVo) {
        //处理时间范围
        if (!StringUtils.isEmpty(inquiryProVo.getDates())) {
            String[] splitTime = inquiryProVo.getDates().split("~");
            SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd");
            try {
                inquiryProVo.setEndDate(format.parse(splitTime[1]));
                inquiryProVo.setStartDate(format.parse(splitTime[0]));
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }

        PageHelper.startPage(page.getPageNum(), page.getPageSize());
        return (Page<BidCurrencyDomain>)inquiryProDao.selectByDomainWhere(inquiryProVo);
    }

    @Override
    public ProjectInfo findByProCode(String proCode) {
        return inquiryProDao.findByProCode(proCode);
    }

    @Override
    public Page<InquiryProDomain> selectMyCheckByDomainWhere(Page<InquiryProDomain> page,
                                                             InquiryProVo inquiryProVo) {
        PageHelper.startPage(page.getPageNum(), page.getPageSize());
        return (Page<InquiryProDomain>)inquiryProDao.selectMyCheckByDomainWhere(inquiryProVo);
    }

    @Override
    public InquiryProVo selectById(String id) {
        return inquiryProDao.selectById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addInquiryPro(InquiryProVo inquiryPro, List<InquiryProCoop> inquiryProCoops,
                              List<InquiryProSub> inquiryProSubs, List<InquiryProAtt> inquiryProAtts) {


        //插入预立项记录
        inquiryProDao.insertById(inquiryPro);

        //批量插入联合体单位
        if(CollectionUtils.isNotEmpty(inquiryProCoops)){
            inquiryProCoopDao.insertByBatch(inquiryProCoops);
        }

        //批量插入子项
        if(CollectionUtils.isNotEmpty(inquiryProSubs)){
            inquiryProSubDao.insertByBatch(inquiryProSubs);
        }

        //批量插入附件
        if(CollectionUtils.isNotEmpty(inquiryProAtts)){
            inquiryProAttDao.insertByBatch(inquiryProAtts);
        }

        // 注意 这里根据不同的业务分支判断条件 获得不同enum
        FlowTemplateEnum templateEnum = FlowTemplateEnum.MKT_INQUIRY_PRO;
        // 处理工作流数据
        wsFlowProcess.launch(templateEnum, inquiryPro.getId(), inquiryPro.getProcessId(), null);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editInquiryPro(InquiryProVo inquiryPro, List<InquiryProAtt> fileAtts, String submitType) {
	    //更新
        inquiryProDao.updateByIdSelective(inquiryPro);
        inquiryProAttDao.deleteByInquiryId(inquiryPro.getId());
        //批量插入附件
        if(CollectionUtils.isNotEmpty(fileAtts)){
            inquiryProAttDao.insertByBatch(fileAtts);
        }
        if("2".equalsIgnoreCase(submitType)){
            inquiryPro=inquiryProDao.selectById(inquiryPro.getId());
            InquiryPro inquiry=new InquiryPro();
            inquiry.setId(inquiryPro.getId());
            inquiry.setProcessStatus("1");//审判中
            inquiryProDao.updateByIdSelective(inquiryPro);
            // 注意 这里根据不同的业务分支判断条件 获得不同enum
            FlowTemplateEnum templateEnum = FlowTemplateEnum.MKT_INQUIRY_PRO;
            // 处理工作流数据
            wsFlowProcess.launch(templateEnum, inquiryPro.getId(), inquiryPro.getProcessId(), null);
        }


    }

    @Override
    public List<InquiryPro> selectUsableInquiryPro() {
        return inquiryProDao.selectUsableInquiryPro();
    }

    @Override
    public List<InquiryPro> selectByProCode(String proCode) {
        return inquiryProDao.selectByProCode(proCode);
    }

    @Override
    public InquiryProJsonVo queryDetailById(String id) {
        InquiryProJsonVo inqProJson = new InquiryProJsonVo();
        //基础信息
        InquiryProDto inqProDto = inquiryProDao.queryDetailById(id);
        //项目业态-文字映射
        ProjectFormatEnum pfe = ProjectFormatEnum.getByCode(inqProDto.getProFormat());
        if (pfe != null) {
            inqProDto.setProFormat(pfe.getName());
        }
        //项目类型-文字映射
        ProjectTypeEnum pte = ProjectTypeEnum.getByCode(inqProDto.getProTypes());
        if (pte != null) {
            inqProDto.setProTypes(pte.getName());
        }
        inqProJson.setInfo(inqProDto);

        //竞争对手信息
        List<InquiryCompany> tmpList = inquiryProDao.queryInqCompByProCode(inqProDto.getProCode());
        if (tmpList != null && tmpList.size() > 0) {
            String[] compnayArr = new String[tmpList.size()];
            for (int i = 0; i < tmpList.size(); i++) {
                compnayArr[i] = tmpList.get(i).getCompanyName();
            }
            inqProJson.setCompnayArr(compnayArr);
        }

        //附件信息表
        List<ProjectAttachment> projectAttaList = projectAttachmentDao.queryByWhere(inqProDto.getProCode(), ProjectFileTypeEnum.FILE_TYPE10.getCode(), null);
        inqProJson.setFileAtt(setupProService.fileAttaListToArray(projectAttaList));
        return inqProJson;
    }

    @Override
    public RspVo editDetail(InquiryPro inquiryPro, InquiryProDto inqProDto, ProjectInfo proInfo, BidInfo bidInfo, PaymentApply paymentApply, PaymentApplyDetail paymentApplyDetail, String[] companyArr, List<ProjectAttachment> attachmentList, AuthorizationVO vo, Integer submitType) {
        //根据pro_code查询项目基础信息
        ProjectInfo tmpProInfo = projectInfoDao.findByProCode(inqProDto.getProCode());
        if (tmpProInfo == null) return RspVo.getFailureResponse(400, "项目基础信息不存在");
        InquiryPro tmpInqPro = inquiryProDao.selectByPrimaryKey(inqProDto.getId());
        if (tmpInqPro == null) return RspVo.getFailureResponse(400, "招标文件分析信息不存在");
        //判断审批状态
        if (StringUtils.isNotBlank(tmpInqPro.getProcessStatus())
                && StringUtils.equals(ProProcesssStatusEnum.PRO_STATUS1.getCode(), tmpInqPro.getProcessStatus())) {
            return RspVo.getFailureResponse(400, "审批状态不正确，操作失败");
        }

        //如果审批状态为已完成(9)，只更新是否通过资审
        if (StringUtils.equals(ProProcesssStatusEnum.PRO_STATUS9.getCode(), tmpInqPro.getProcessStatus())) {
            if (StringUtils.isNotBlank(tmpInqPro.getIsThrough())
                    && StringUtils.equals(YesOrNoEnum.NO.getCode(), tmpInqPro.getIsThrough())) {
                throw new FlowProcessException("该项目已终止");
            }
            BidAnalysis tmpBa = bidAnalysisDao.queryByProCode(tmpInqPro.getProCode());
            if (tmpBa != null) throw new FlowProcessException("该项目已进入后续流程，无法编辑");
            next(tmpInqPro, inqProDto, vo, companyArr, tmpProInfo, tmpBa);
            return RspVo.getSuccessResponse();
        }
        //驳回有两种
        //1.资格预审信息被驳回
        //2.是否通过资格预审选择否被驳回
        if (StringUtils.equals(ProProcesssStatusEnum.PRO_STATUS10.getCode(), tmpInqPro.getProcessStatus())) {
            if (StringUtils.isNotBlank(tmpInqPro.getIsThrough())
                    && (StringUtils.equals(YesOrNoEnum.NO.getCode(), tmpInqPro.getIsThrough())
                    || StringUtils.equals(YesOrNoEnum.YES.getCode(), tmpInqPro.getIsThrough()))) {
                //这里为是否通过资格预审选择否被驳回走的流程
                BidAnalysis tmpBa = bidAnalysisDao.queryByProCode(tmpInqPro.getProCode());
                if (tmpBa != null) throw new FlowProcessException("该项目已进入后续流程，无法编辑");
                next(tmpInqPro, inqProDto, vo, companyArr, tmpProInfo, tmpBa);
                return RspVo.getSuccessResponse();
            }
        }

        proInfo.setId(tmpProInfo.getId());
        proInfo.setUptBy(vo.getId());
        proInfo.setUptTime(new Date());
        //更新项目基础信息
        projectInfoDao.modifyProjectInfoBySeletive(proInfo);

        //如果是资格预审，需要填写下面数据，如果是资格后审，下面数据不需要
        if (StringUtils.equals(InquiryTypeEnum.INQ_TYPE0.getCode(), proInfo.getQualificationType())) {
            //更新资格预审数据
            inquiryPro.setId(tmpInqPro.getId());
            inquiryPro.setUptBy(vo.getId());
            inquiryPro.setUptTime(new Date());
            inquiryProDao.updateByIdSelective(inquiryPro);

            //更新投标信息
            BidInfo tmpBidInfo = bidInfoDao.queryByProCode(inqProDto.getProCode());
            bidInfo.setProCode(inqProDto.getProCode());
            bidInfo.setSignupLead(inqProDto.getSignupLead());
            bidInfo.setIsNeedUnit(inqProDto.getIsNeedUnit());
            bidInfo.setUnit(inqProDto.getUnit());
            bidInfo.setUptBy(vo.getId());
            bidInfo.setUptTime(new Date());
            if (tmpBidInfo == null) {
                bidInfo.setAddBy(vo.getId());
                bidInfo.setAddTime(new Date());
                bidInfoDao.insert(bidInfo);
            } else {
                bidInfo.setId(tmpBidInfo.getId());
                bidInfoDao.modifyById(bidInfo);
            }

            //判断选择是否需要保证金，需要保证金录入下列信息
            if (StringUtils.equals(YesOrNoEnum.YES.getCode(), inquiryPro.getIsNeedBond())) {
                //付款申请
                String payApplyId = paymentApplyDao.querySguidByProCode(inqProDto.getProCode(), "1");
                StaffInfo staffInfo = staffInfoDao.selectByPrimaryKey(vo.getHrStaffId());
                if (staffInfo == null) throw new FlowProcessException("获取不到对应的人员信息数据~");
                if (StringUtils.isBlank(payApplyId)) {
                    paymentApply.setCodes(IdFactory.getUUIDUpper());
                    paymentApply.setProCode(inqProDto.getProCode());
                    paymentApply.setProName(tmpProInfo.getProName());
                    paymentApply.setProFormat(tmpProInfo.getProFormat());
                    paymentApply.setHrOrgId(staffInfo.getPkOrg());
                    paymentApply.setHrDeptId(staffInfo.getPkDept());
                    paymentApply.setHrStaffApplyId(vo.getHrStaffId());
                    paymentApply.setStaffName(staffInfo.getStaffName());
                    paymentApply.setApplyPayDate(new Date());
                    paymentApply.setPayTotal(inqProDto.getBondAmt());
                    paymentApply.setPayReason("保证金付款申请");
                    paymentApply.setAddBy(vo.getId());
                    paymentApply.setAddTime(new Date());
                    paymentApply.setTypes("1");
                    paymentApplyDao.insertSelective(paymentApply);
                    payApplyId = paymentApply.getId();
                } else {
                    paymentApply.setCodes(IdFactory.getUUIDUpper());
                    paymentApply.setProCode(inqProDto.getProCode());
                    paymentApply.setProName(tmpProInfo.getProName());
                    paymentApply.setProFormat(tmpProInfo.getProFormat());
                    paymentApply.setHrOrgId(staffInfo.getPkOrg());
                    paymentApply.setHrDeptId(staffInfo.getPkDept());
                    paymentApply.setHrStaffApplyId(vo.getHrStaffId());
                    paymentApply.setStaffName(staffInfo.getStaffName());
                    paymentApply.setApplyPayDate(new Date());
                    paymentApply.setPayTotal(inqProDto.getBondAmt());
                    paymentApply.setPayReason("资格预审保证金付款申请");
                    paymentApply.setUptBy(vo.getId());
                    paymentApply.setUptTime(new Date());
                    paymentApply.setTypes("1");
                    paymentApplyDao.updateByIdSelective(paymentApply);
                }

                //付款明细
                PaymentApplyDetail tmpPad = paymentApplyDetailDao.selectByPaymentApplyId(payApplyId);
                if (tmpPad == null) {
                    paymentApplyDetail.setApplyId(payApplyId);
                    paymentApplyDetail.setItemName("资格预审保证金付款");
                    paymentApplyDetail.setPaySingle(paymentApply.getPayTotal());
                    paymentApplyDetail.setAddBy(vo.getId());
                    paymentApplyDetail.setAddTime(new Date());
                    paymentApplyDetailDao.insertSelective(paymentApplyDetail);
                } else {
                    paymentApplyDetail.setId(tmpPad.getId());
                    paymentApplyDetail.setApplyId(payApplyId);
                    paymentApplyDetailDao.updateByIdSelective(paymentApplyDetail);
                }
            }
        }

        //更新附件信息
        projectAttachmentDao.deleteByWhere(inqProDto.getProCode(), ProjectFileTypeEnum.FILE_TYPE10.getCode(), null);
        if (attachmentList != null && attachmentList.size() > 0) {
            projectAttachmentDao.insertBatch(attachmentList);
        }

        if (submitType == 1) {
            //处理OA待办信息
            if (StringUtils.isNotBlank(tmpInqPro.getOaId())) {
                oaFlowService.finishOA(tmpInqPro.getOaId());
            }
            String detailJson = JSON.toJSONString(queryDetailById(inqProDto.getId()));
            proProcessManageService.sendProcess(ProProcessDetailTypeEnum.PRO_NODE_TYPE4, detailJson, inqProDto.getId(), inqProDto.getProCode(), vo);
        }
        return RspVo.getSuccessResponse();
    }

    public void next(InquiryPro tmpInqPro, InquiryProDto inqProDto, AuthorizationVO vo,
                     String[] companyArr, ProjectInfo tmpProInfo, BidAnalysis tmpBa) {
        InquiryPro uptInqPro = new InquiryPro();
        uptInqPro.setId(tmpInqPro.getId());
        uptInqPro.setIsThrough(inqProDto.getIsThrough());
        uptInqPro.setUptBy(vo.getId());
        uptInqPro.setUptTime(new Date());
        inquiryProDao.updateByIdSelective(uptInqPro);
        //如果资审未通过，发起流程
        if (StringUtils.equals(YesOrNoEnum.NO.getCode(), inqProDto.getIsThrough())) {
            String detailJson = JSON.toJSONString(queryDetailById(inqProDto.getId()));
            proProcessManageService.sendProcess(ProProcessDetailTypeEnum.PRO_NODE_TYPE21, detailJson, tmpInqPro.getId(), tmpInqPro.getProCode(), vo);
            //处理OA待办信息
            if (StringUtils.isNotBlank(tmpInqPro.getOaId())) {
                oaFlowService.finishOA(tmpInqPro.getOaId());
            }
        } else if (StringUtils.equals(YesOrNoEnum.YES.getCode(), inqProDto.getIsThrough())) {
            //录入竞争对手单位名称
            if (companyArr != null && companyArr.length > 0) {
                List<InquiryCompany> list = new ArrayList<>();
                InquiryCompany inqComp;
                for (String companyName : companyArr) {
                    if (StringUtils.isBlank(companyName)) continue;
                    inqComp = new InquiryCompany();
                    inqComp.setCodes(IdFactory.getUUIDUpper());
                    inqComp.setProCode(tmpProInfo.getProCode());
                    inqComp.setCompanyName(companyName);
                    inqComp.setAddBy(vo.getId());
                    inqComp.setAddTime(new Date());
                    list.add(inqComp);
                }
                if (list.size() > 0) {
                    inquiryProDao.insertBatchInqCompInfo(list);
                }
            }
            //通过资格预审发起招标文件分析
            if (tmpBa == null) {
                BidAnalysis bidAnalysis = new BidAnalysis();
                bidAnalysis.setCodes(IdFactory.getUUIDUpper());
                bidAnalysis.setProCode(tmpInqPro.getProCode());
                bidAnalysis.setAddBy(vo.getId());
                bidAnalysis.setAddTime(new Date());
                bidAnalysis.setUptBy(vo.getId());
                bidAnalysis.setUptTime(new Date());
                bidAnalysisDao.insertByProcess(bidAnalysis);
                //给营销经理发送招标文件分析待办
                String oaTitle = UtilTools.getMktOaTitle(tmpProInfo, ProProcessDetailTypeEnum.PRO_NODE_TYPE5);
                String oaId = oaFlowService.sendOAToDo(oaTitle, vo.getId(), vo.getId(), FlowTemplateEnum.MKT_BID_ANALYSIS.getSrcBizTable(), bidAnalysis.getId());
                if (StringUtils.isNotBlank(oaId)) {
                    bidAnalysis.setOaId(oaId);
                    bidAnalysisDao.modifyById(bidAnalysis);
                }
            }
            //判断是否需要保证金，选择是往保证金申请写入资格预审保证金记录
            if (StringUtils.equals(YesOrNoEnum.YES.getCode(), tmpInqPro.getIsNeedBond())) {
                //往保证金申请里面写入一条资格预审保证金申请记录并给资格预审流程中的财务人员发送待办
                BidBondApply bidBondApply = new BidBondApply();
                bidBondApply.setCodes(IdFactory.getUUIDUpper());
                bidBondApply.setProCode(tmpInqPro.getProCode());
                bidBondApply.setBailMethod(tmpInqPro.getBailMethod() != null ? tmpInqPro.getBailMethod() : "");
                bidBondApply.setReviewMemo("");
                bidBondApply.setAddBy(vo.getId());
                bidBondApply.setAddTime(new Date());
                bidBondApply.setUptBy(vo.getId());
                bidBondApply.setUptTime(new Date());
                bidBondApply.setProcessId("");
                bidBondApply.setProcessStatus("0");
                bidBondApply.setBondType(BidBondApplyTypeEnum.BBA_TYPE1.getCode());
                bidBondApplyDao.insert(bidBondApply);
                //更新Id设置到付款申请主表中
                String applyId = paymentApplyDao.querySguidByProCode(tmpInqPro.getProCode(), "1");
                if (StringUtils.isBlank(applyId)) throw new FlowProcessException("保证金申请信息为空");
                PaymentApply tmpPa = new PaymentApply();
                tmpPa.setId(applyId);
                tmpPa.setBizSguid(bidBondApply.getId());
                paymentApplyDao.updateByIdSelective(tmpPa);
                //给流程中的财务人员发送待办信息
                List<String> finIdList = proProcessManageService.queryFinanceUserIdByProcessId(tmpInqPro.getProcessId(), PostGroupEnum.FINANCE.getCode());
                if (finIdList != null && finIdList.size() > 0) {
                    String bidBondApplyTitle = UtilTools.getMktOaTitle(tmpProInfo, ProProcessDetailTypeEnum.PRO_NODE_TYPE8);
                    String oaId = oaFlowService.sendOAToDo(bidBondApplyTitle, vo.getId(), finIdList.get(0), FlowTemplateEnum.MKT_BID_BOND_APPLY.getSrcBizTable(), bidBondApply.getId());
                    if (StringUtils.isNotBlank(oaId)) {
                        proProcessManageService.modifyOaIdById(FlowTemplateEnum.MKT_BID_BOND_APPLY.getSrcBizTable(), oaId, bidBondApply.getId());
                    }
                }
                //投标保证金逻辑和这个一致(招标文件分析)
            }
            //处理OA待办信息
            if (StringUtils.isNotBlank(tmpInqPro.getOaId())) {
                oaFlowService.finishOA(tmpInqPro.getOaId());
            }
        }
    }
}
